package com.qd.pay.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cdqidi.constant.ConstantDto;
import com.cdqidi.dto.ApiResult;
import com.cdqidi.dto.CacheKey;
import com.cdqidi.exception.ApiException;
import com.cdqidi.util.RedisTemplateUtil;
import com.qd.pay.domain.OrderRefundWxReportDTO;
import com.qd.pay.model.OrderRefundWxReport;
import com.qd.pay.repository.OrderRefundWxReportRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * @author sjk
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderRefundWxReportService {

    private final OrderRefundWxReportRepository orderRefundWxReportRepository;
    @Resource
    private RedisTemplateUtil<OrderRefundWxReport> redisTemplateUtil;

    private static final String PREFIX_ID = "m_order_refund_wx_report_rid_{0}";

    @Transactional(rollbackFor = Exception.class)
    public OrderRefundWxReport save(OrderRefundWxReport model) throws ApiException {
        try {
            if (!orderRefundWxReportRepository.save(model)) {
                throw new ApiException(ApiResult.error());
            }
            return model;
        } finally {
            clearCache(model);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean updateById(OrderRefundWxReport model) throws ApiException {
        final OrderRefundWxReport historyModel = Optional.ofNullable(getById(model.getRid())).orElseThrow(() -> new ApiException("ID不存在,不能更新"));
        try {
            if (!orderRefundWxReportRepository.updateById(model)) {
                throw new ApiException(ApiResult.error());
            }
            return true;
        } finally {
            clearCache(historyModel);
            historyModel.freeData();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean removeById(String rid) throws ApiException {
        final OrderRefundWxReport historyModel = Optional.ofNullable(getById(rid)).orElseThrow(() -> new ApiException("ID不存在,不能删除"));
        try {
            if (!orderRefundWxReportRepository.removeById(rid)) {
                throw new ApiException(ApiResult.error());
            }
            return true;
        } finally {
            clearCache(historyModel);
            historyModel.freeData();
        }
    }

    public Boolean isExists(String rid) {
        return orderRefundWxReportRepository.isExists(rid);
    }

    public OrderRefundWxReport getById(String rid) {
        String key = RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, rid);
        return redisTemplateUtil.get(new CacheKey().setKey(key).setTimeout(ConstantDto.REDIS_TIME_OUT_DAY * 3), () -> orderRefundWxReportRepository.getById(rid), OrderRefundWxReport.class);
    }

    public IPage<OrderRefundWxReportDTO> page(Page<OrderRefundWxReportDTO> page, OrderRefundWxReport model) {
        QueryWrapper<OrderRefundWxReport> queryWrapper = new QueryWrapper<>(model);
        IPage<OrderRefundWxReport> iPage = orderRefundWxReportRepository.page(page.convert(this::dtoToModel), queryWrapper);
        return iPage.convert(this::modelToDto);
    }


    private void clearCache(OrderRefundWxReport model) {
        if (null == model) {
            return;
        }
        String key = RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, model.getRid());
        redisTemplateUtil.deleteByKey(key);
    }

    public OrderRefundWxReportDTO modelToDto(OrderRefundWxReport model) {
        if (null == model) {
            return null;
        }
        OrderRefundWxReportDTO dto = new OrderRefundWxReportDTO();
        dto.setRid(model.getRid());
        dto.setOutTradeNo(model.getOutTradeNo());
        dto.setTotalFee(model.getTotalFee());
        dto.setSettlementTotalFee(model.getSettlementTotalFee());
        dto.setFeeType(model.getFeeType());
        dto.setCashFee(model.getCashFee());
        dto.setRefundCount(model.getRefundCount());
        dto.setRefundId(model.getRefundId());
        dto.setRefundChannel(model.getRefundChannel());
        dto.setSettlementRefundFee(model.getSettlementRefundFee());
        dto.setCouponType(model.getCouponType());
        dto.setCouponRefundFee(model.getCouponRefundFee());
        dto.setCouponRefundCount(model.getCouponRefundCount());
        dto.setCouponRefundId(model.getCouponRefundId());
        dto.setCouponRefundFeeOne(model.getCouponRefundFeeOne());
        dto.setRefundStatus(model.getRefundStatus());
        dto.setRefundAccount(model.getRefundAccount());
        dto.setRefundNo(model.getRefundNo());
        dto.setOrderId(model.getOrderId());
        model.freeData();
        return dto;
    }

    public OrderRefundWxReport dtoToModel(OrderRefundWxReportDTO dto) {
        if (null == dto) {
            return null;
        }
        OrderRefundWxReport model = new OrderRefundWxReport();
        model.setRid(dto.getRid());
        model.setOutTradeNo(dto.getOutTradeNo());
        model.setTotalFee(dto.getTotalFee());
        model.setSettlementTotalFee(dto.getSettlementTotalFee());
        model.setFeeType(dto.getFeeType());
        model.setCashFee(dto.getCashFee());
        model.setRefundCount(dto.getRefundCount());
        model.setRefundId(dto.getRefundId());
        model.setRefundChannel(dto.getRefundChannel());
        model.setSettlementRefundFee(dto.getSettlementRefundFee());
        model.setCouponType(dto.getCouponType());
        model.setCouponRefundFee(dto.getCouponRefundFee());
        model.setCouponRefundCount(dto.getCouponRefundCount());
        model.setCouponRefundId(dto.getCouponRefundId());
        model.setCouponRefundFeeOne(dto.getCouponRefundFeeOne());
        model.setRefundStatus(dto.getRefundStatus());
        model.setRefundAccount(dto.getRefundAccount());
        model.setRefundNo(dto.getRefundNo());
        model.setOrderId(dto.getOrderId());
        dto.freeData();
        return model;
    }

}